<?php
namespace app\nadmin\controller;
use app\nadmin\model\LoginIpLog_M;
use app\nadmin\model\Menu_M;
use app\nadmin\model\Role_M;
use think\Controller;
use app\nadmin\model\Adminer_M;
use think\facade\Session;
use think\Validate;
use think\facade\Cookie;
/**
 * 后台管理员登陆操作类
 */

class Login extends Controller
{
    protected $adminerM;
    protected $errorMsg = "";

    //初始化 模型类实例
    public function initialize()
    {
        $this->adminerM = new Adminer_M();
    }

    public function __set($name, $value)
    {
        if(isset($this->$name))
        {
            $this->$name = $value;
        }
    }
    public function __get($name)
    {
       if(isset($this->$name))
       {
           return $this->$name;
       }
        return false;
    }

    //登陆页面
    public function index()
    {
        return $this->fetch();
    }
    //登陆操作
    public function login()
    {
        $username = $this->request->username;
        $pwd = $this->request->password;

        //验证数据格式
        $rule = [
            'username'=> 'require|alphaDash|min:6|max:12', //字母数字下划线
            'pwd' =>'require|alphaDash|min:6|max:12', //字母数字下划线
        ];
        $data = [
            'username' => $username,
            'pwd'=>$pwd,
        ];
        $validate = Validate::make($rule,[]);

        if(!$validate->check($data))
        {
            return echojson($validate->getError(),0);
        }

        //账号密码匹配
        $field = "id,role_id,username,pwd,salt,name,status,email,phone,portrait";
        $where = "username='{$username}'"; //登陆账号唯一

        $infoData = $this->adminerM->getOne($field,$where);
        if($infoData)
        {
            //数据匹配
            if($infoData['status'] != 1)
            {
                return echojson('该账号已被冻结',0);
            }

            if($infoData['pwd'] !== createPwd($pwd,$infoData['salt']))
            {
                return echojson('密码错误',0);
            }

            //尚未设置角色
            if($infoData['role_id'] <= 0)
            {
                return echojson('该账号尚无任何角色',0);
            }
            if($this->setRoleAndMenu($infoData)){
                //记录登陆IP
                $this->setLoginIp($infoData['id']);
                return echojson("登陆成功",1);
            }else{
                return echojson($this->errorMsg,1);
            }


        }else{
            return echojson("账号不存在",0);
        }
    }

    /*
     * @explain 获取存储信息 --并完成存储操作
     */
    public function setRoleAndMenu($infoData)
    {
        $role = $this->getRole($infoData['role_id']);
        if($role['status'] != 1)
        {
            $this->errorMsg = '该账号角色已被禁用';
            return false;
        }

        //获取权限和菜单
        $power = $this->getPower($role['menu_ids']);

        //存储信息
        $info = [
            'id'=>$infoData['id'],
            'username'=>$infoData['username'],
            'name'=>$infoData['name'],
            'status'=>$infoData['status'],
            'email'=>$infoData['email'],
            'phone'=>$infoData['phone'] ? $infoData['phone'] : '',
            'portrait'=>$infoData['portrait'],
            'role'=>$role['role'],
        ];

        $this->setLogin($info,$power);
        return true;
    }

    /*
     * @explain 读取角色
     * @param $role_id int 角色ID
     */
    protected function getRole($role_id)
    {
        $roleM = new Role_M();
        $roleList = $roleM->getOne("role,menu_ids,status","id=$role_id");
        return $roleList;
    }
    /*
     * @explain 读取权限
     * @param 菜单id集合 $menuIds string
     */
    protected function getPower($menuIds)
    {
        if(empty($menuIds))
        {
            //无任何权限
            return ['power'=>0,'menu'=>[]];
        }else{
            $menuM = new Menu_M();
            $menuList = $menuM->getMore("id,title,pid,lev,controller,action,d_type,sort,module"," status=1");
            return $this->joinControllerAndAction($menuList,$menuIds);
        }
    }

    /*
     * @explain 菜单控制器和方法数据拼接
     */
    protected function joinControllerAndAction($menuList,$menuIds)
    {

        if(is_array($menuList) && $menuList)
        {
            $menuIdArr = explode(',',$menuIds);
            $powerList = [];
            $menu = [];
            $doNotCheckMenu = []; //菜单中表格 接口
            foreach($menuList as $v)
            {
                $v['url'] = strtolower($v['module'].'/'.$v['controller'].'/'.$v['action']);
                if(in_array($v['id'],$menuIdArr)){
                    $powerList[] = $v['url'];
                    if($v['d_type'] == 0) $menu[$v['id']] = $v; //记录菜单
                }
                if($v['d_type'] == 2) $doNotCheckMenu[$v['id']] = $v['url']; //不参与权限验证的菜单
            }
            $menu = getTree_1($menu);

            $list = [
                'power' => $powerList,
                'menu' => $menu,
                'doNotCheckMenu' => $doNotCheckMenu,
            ];

            return $list;
        }
        return [];
    }
    /*
     * @explain 登陆成功 -- 存cookie和session
     * @param $info [] 用户相关信息数据 ，$power []/int 权限数据  0 - 超级管理员
     */
    protected function setLogin($info,$power)
    {
        //管理员Id存cookie 有效时间1小时
        Cookie::set("adminerId",$info['id'],3600);
        //管理员信息
        setAdminInfo($info);
        //权限数据存session 有效实时间1小时
        Session::set("adminerPower_".$info['id'],$power['power']);
        //菜单存session
        Session::set("menu_".$info['id'],$power['menu']);
        //不做校验的菜单存session
        Session::set("doNotCheckMenu_".$info['id'],$power['doNotCheckMenu']);
        //验证token存入session 有效期1小时
        $token = createAdminerToken($info['id']);
        Session::set("adminerToken_".$info['id'],$token);

    }

    /*
     * @explain 退出登录
     */
    public function loginOut()
    {
        $adminerId = Cookie::get("adminerId");
        Cookie::delete("adminerId");
        Session::delete("adminerInfo_".$adminerId);
        Session::delete("adminerPower_".$adminerId);
        Session::delete("menu_".$adminerId);
        Session::delete("doNotCheckMenu_".$adminerId);
        Session::delete("adminerToken_".$adminerId);
        $loginUrl = createUrl('nadmin/login/index');
        header("Location:".$loginUrl);
    }

    /*
     * @explain 记录登陆IP
     */
    public function setLoginIp($id)
    {
        $loginIpLog_M = new LoginIpLog_M();
        $data = [
            'adminerId'=>$id,
            'ip'=>ip2long(getip()),
            'ctime'=>date('Y-m-d H:i:s',time())
        ];
        $loginIpLog_M->insertOne($data);
    }
}